using Microsoft.EntityFrameworkCore;
using Order.Api.Read.Application.Command;
using Order.Api.Read.Dto.Order;
using Order.Domain.Enum;
using Order.ErrorCode;
using Order.Interstructrue;
using System.Reflection;

namespace Order.Api.Read.Service.InterrogationOrderService
{
    /// <summary>
    /// 问诊订单服务实现
    /// </summary>
    public class InterrogationOrderService : IInterrogationOrderService
    {
        private readonly MedicalDbContext _context;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="context">数据库上下文</param>
        public InterrogationOrderService(MedicalDbContext context)
        {
            _context = context ?? throw new ArgumentNullException(nameof(context));
        }

        /// <summary>
        /// 获取问诊订单分页数据
        /// </summary>
        /// <param name="command">查询命令</param>
        /// <returns>分页结果</returns>
        public async Task<ApiPageIng<InterrogationOrderPageDto>> GetInterrogationOrderPageAsync(InterrogationOrderPageCommand command)
        {
            try
            {
                if (command?.Query == null)
                {
                    throw new ArgumentNullException(nameof(command));
                }

                // 构建查询
                var query = from io in _context.InterrogationOrder
                            join p in _context.Patient on io.PatientId equals p.Id into patientJoin
                            from p in patientJoin.DefaultIfEmpty()
                            where !io.IsDeleted
                            select new InterrogationOrderPageDto
                            {
                                Id = io.Id,
                                OrderNo = io.OrderNo,
                                CreateTime = io.CreateTime,
                                PatientName = p.PatientName,
                                PatientId = io.PatientId,
                                ConsultationMethod = io.OrderType,
                                ConsultationSource = io.OrderType,
                                ConsultationFee = 20, // 示例值，实际应该从数据库获取
                                OrderStatus = io.Status
                            };

                // 应用查询条件
                query = ApplyQueryConditions(query, command.Query);

                // 排序
                query = query.OrderByDescending(x => x.CreateTime);

                // 获取总数
                var totalCount = await query.CountAsync();

                // 分页
                var pageData = await query
                    .Skip((command.Query.PageIndex - 1) * command.Query.PageSize)
                    .Take(command.Query.PageSize)
                    .ToListAsync();

                // 设置枚举名称
                foreach (var item in pageData)
                {
                    item.OrderStatusName = GetEnumName(item.OrderStatus);
                    item.ConsultationMethodName = GetEnumName(item.ConsultationMethod);
                    item.ConsultationSourceName = GetEnumName(item.ConsultationSource);
                    item.Department = "内科"; // 示例值，实际应该从数据库获取
                    item.Doctor = "张三"; // 示例值，实际应该从数据库获取
                }

                // 构建分页结果
                var result = new ApiPageIng<InterrogationOrderPageDto>
                {
                    PageIndex = command.Query.PageIndex,
                    PageSize = command.Query.PageSize,
                    TotalCount = totalCount,
                    TotalPages = (int)Math.Ceiling((double)totalCount / command.Query.PageSize),
                    Data = pageData
                };

                return result;
            }
            catch (Exception ex)
            {
                // 记录异常日志
                // TODO: 添加日志记录
                throw new Exception($"获取问诊订单分页数据时发生错误: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 获取问诊订单详情
        /// </summary>
        /// <param name="command">查询命令</param>
        /// <returns>订单详情</returns>
        public async Task<ApiResult<InterrogationOrderDetailDto>> GetInterrogationOrderDetailAsync(InterrogationOrderDetailCommand command)
        {
            try
            {
                if (command == null)
                {
                    throw new ArgumentNullException(nameof(command));
                }

                if (command.Id <= 0)
                {
                    throw new ArgumentException("订单ID必须大于0", nameof(command.Id));
                }

                // 构建查询 - 关联问诊订单、患者和问诊详情
                var query = from io in _context.InterrogationOrder
                            join p in _context.Patient on io.PatientId equals p.Id into patientJoin
                            from p in patientJoin.DefaultIfEmpty()
                            join i in _context.Interrogation on io.Id equals i.InterrogationOrderId into interrogationJoin
                            from i in interrogationJoin.DefaultIfEmpty()
                            where io.Id == command.Id && !io.IsDeleted
                            select new InterrogationOrderDetailDto
                            {
                                // 订单信息
                                Id = io.Id,
                                OrderNo = io.OrderNo,
                                OrderType = io.OrderType,
                                Status = io.Status,
                                PaymentMethod = io.PaymentMethod,
                                PaymentTime = io.PaymentTime,
                                CreateTime = io.CreateTime,
                                PatientId = io.PatientId,
                                WithdrawnCause = io.WithdrawnCause,
                                PaymentMethodName = io.PaymentMethod.ToString(),
                                // 患者信息
                                PatientName = p.PatientName,
                                Sex = p.Sex,
                                Age = p.Age,
                                Phone = p.Phone,
                                Address = p.Address,

                                // 问诊详情
                                InterrogationId = i.Id,
                                ConsultationTime = i.ConsultationTime,
                                CallDuration = i.CallDuration,
                                PatientRating = i.PatientRating,
                                PatientReview = i.PatientReview
                            };

                var result = await query.FirstOrDefaultAsync();

                if (result == null)
                {
                    return new ApiResult<InterrogationOrderDetailDto>
                    {
                        Code = ApiEnums.NotFound,
                        Msg = "未找到指定的问诊订单",
                        Data = null
                    };
                }

                // 设置枚举名称
                result.OrderTypeName = GetEnumName(result.OrderType);
                result.StatusName = GetEnumName(result.Status);
                //result.PaymentMethodName = GetEnumName(result.PaymentMethod);
                result.GenderName = GetGenderName(result.Sex);

                // 设置示例数据（实际应该从数据库获取）
                //result.AmountPayable = 40;
                //result.CouponAmount = 10;
                //result.ActualPayment = 30;
                //result.AppointmentTime = result.CreateTime.AddHours(6); // 预约时间示例
                //result.SubmissionTime = result.CreateTime;
                //result.ConditionDescription = "最近一个月总是头晕、头痛、疲劳、心悸等，有时还会出现注意力不集中、记忆力减退、肢体麻木的现象";
                //result.ConsultationStatus = "未去医院就诊过";

                return new ApiResult<InterrogationOrderDetailDto>
                {
                    Code = ApiEnums.Success,
                    Msg = "获取问诊订单详情成功",
                    Data = result
                };
            }
            catch (Exception ex)
            {
                // 记录异常日志
                // TODO: 添加日志记录
                return new ApiResult<InterrogationOrderDetailDto>
                {
                    Code = ApiEnums.Fail,
                    Msg = $"获取问诊订单详情时发生错误: {ex.Message}",
                    Data = null
                };
            }
        }

        /// <summary>
        /// 应用查询条件
        /// </summary>
        /// <param name="query">查询对象</param>
        /// <param name="queryDto">查询条件</param>
        /// <returns>应用条件后的查询对象</returns>
        private IQueryable<InterrogationOrderPageDto> ApplyQueryConditions(IQueryable<InterrogationOrderPageDto> query, InterrogationOrderQueryDto queryDto)
        {
            // 关键字搜索（患者姓名、手机号）
            if (!string.IsNullOrWhiteSpace(queryDto.Keyword))
            {
                var keyword = queryDto.Keyword.Trim();
                query = query.Where(x =>
                    (x.PatientName != null && x.PatientName.Contains(keyword))
                );
            }

            // 订单状态筛选
            if (queryDto.OrderStatus.HasValue)
            {
                query = query.Where(x => x.OrderStatus == queryDto.OrderStatus.Value);
            }

            // 问诊方式筛选
            if (queryDto.ConsultationMethod.HasValue)
            {
                query = query.Where(x => x.ConsultationMethod == queryDto.ConsultationMethod.Value);
            }

            // 问诊来源筛选
            if (queryDto.ConsultationSource.HasValue)
            {
                query = query.Where(x => x.ConsultationSource == queryDto.ConsultationSource.Value);
            }

            // 时间范围筛选
            if (queryDto.StartTime.HasValue)
            {
                query = query.Where(x => x.CreateTime >= queryDto.StartTime.Value);
            }

            if (queryDto.EndTime.HasValue)
            {
                query = query.Where(x => x.CreateTime <= queryDto.EndTime.Value);
            }

            return query;
        }

        /// <summary>
        /// 获取枚举名称
        /// </summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="enumValue">枚举值</param>
        /// <returns>枚举名称</returns>
        private string? GetEnumName<T>(T? enumValue) where T : struct, Enum
        {
            if (!enumValue.HasValue)
                return null;

            var field = enumValue.Value.GetType().GetField(enumValue.Value.ToString());
            if (field == null)
                return enumValue.Value.ToString();

            var attribute = field.GetCustomAttribute<System.ComponentModel.DescriptionAttribute>();
            return attribute?.Description ?? enumValue.Value.ToString();
        }

        /// <summary>
        /// 获取性别名称
        /// </summary>
        /// <param name="sex">性别值</param>
        /// <returns>性别名称</returns>
        private string? GetGenderName(string? sex)
        {
            return sex switch
            {
                "女" => "女",
                "男" => "男",
                _ => "未知"
            };
        }
    }
} 